﻿using System;
using System.Collections;
using UnityEngine;

// Token: 0x0200012C RID: 300
[AddComponentMenu("RVP/C#/AI/Follow AI", 0)]
[DisallowMultipleComponent]
[RequireComponent(typeof(VehicleParent))]
public class FollowAI : MonoBehaviour
{
	// Token: 0x06000581 RID: 1409 RVA: 0x0002ADD8 File Offset: 0x00028FD8
	private void Start()
	{
		this.tr = base.transform;
		this.rb = base.GetComponent<Rigidbody>();
		this.vp = base.GetComponent<VehicleParent>();
		this.va = base.GetComponent<VehicleAssist>();
		this.initialSpeed = this.speed;
		this.InitializeTarget();
	}

	// Token: 0x06000582 RID: 1410 RVA: 0x0002AE28 File Offset: 0x00029028
	private void FixedUpdate()
	{
		if (this.target)
		{
			if (this.target != this.targetPrev)
			{
				this.InitializeTarget();
			}
			this.targetPrev = this.target;
			this.targetIsWaypoint = this.target.GetComponent<VehicleWaypoint>();
			this.targetVisible = !Physics.Linecast(this.tr.position, this.target.position, this.viewBlockMask);
			if (this.targetVisible || this.targetIsWaypoint)
			{
				this.targetPoint = ((!this.targetBody) ? this.target.position : (this.target.position + this.targetBody.velocity));
			}
			if (this.targetIsWaypoint && (this.tr.position - this.target.position).sqrMagnitude <= this.targetWaypoint.radius * this.targetWaypoint.radius)
			{
				this.target = this.targetWaypoint.nextPoint.transform;
				this.targetWaypoint = this.targetWaypoint.nextPoint;
				this.prevSpeed = this.speed;
				this.speed = Mathf.Clamp01(this.targetWaypoint.speed * this.initialSpeed);
				this.brakeTime = this.prevSpeed / this.speed;
				if (this.brakeTime <= 1f)
				{
					this.brakeTime = 0f;
				}
			}
			this.brakeTime = Mathf.Max(0f, this.brakeTime - Time.fixedDeltaTime);
			this.close = ((this.tr.position - this.target.position).sqrMagnitude <= Mathf.Pow(this.followDistance, 2f) && !this.targetIsWaypoint);
			this.dirToTarget = (this.targetPoint - this.tr.position).normalized;
			this.lookDot = Vector3.Dot(this.vp.forwardDir, this.dirToTarget);
			this.steerDot = Vector3.Dot(this.vp.rightDir, this.dirToTarget);
			this.stoppedTime = ((Mathf.Abs(this.vp.localVelocity.z) >= 1f || this.close || this.vp.groundedWheels <= 0) ? 0f : (this.stoppedTime + Time.fixedDeltaTime));
			if (this.stoppedTime > this.stopTimeReverse && this.reverseTime == 0f)
			{
				this.reverseTime = this.reverseAttemptTime;
				this.reverseAttempts++;
			}
			if (this.reverseAttempts > this.resetReverseCount && this.resetReverseCount >= 0)
			{
				base.StartCoroutine(this.ReverseReset());
			}
			this.reverseTime = Mathf.Max(0f, this.reverseTime - Time.fixedDeltaTime);
			if (this.targetVelocity > 0f)
			{
				this.speedLimit = Mathf.Clamp01(this.targetVelocity - this.vp.localVelocity.z);
			}
			else
			{
				this.speedLimit = 1f;
			}
			this.vp.SetAccel((this.close || (this.lookDot <= 0f && this.vp.localVelocity.z >= 5f) || this.vp.groundedWheels <= 0 || this.reverseTime != 0f) ? 0f : (this.speed * this.speedLimit));
			this.vp.SetBrake((this.reverseTime != 0f || this.brakeTime != 0f || (this.close && this.vp.localVelocity.z > 0.1f)) ? ((this.reverseTime <= 0f) ? ((this.brakeTime <= 0f) ? (1f - Mathf.Clamp01(Vector3.Distance(this.tr.position, this.target.position) / Mathf.Max(0.01f, this.followDistance))) : (this.brakeTime * 0.2f)) : 1f) : ((this.lookDot >= 0.5f || this.lookDot <= 0f || this.vp.localVelocity.z <= 10f) ? 0f : (0.5f - this.lookDot)));
			this.vp.SetSteer((this.reverseTime != 0f) ? (-Mathf.Sign(this.steerDot) * (float)((!this.close) ? 1 : 0)) : (Mathf.Abs(Mathf.Pow(this.steerDot, (float)(((this.tr.position - this.target.position).sqrMagnitude <= 20f) ? 2 : 1))) * Mathf.Sign(this.steerDot)));
			this.vp.SetEbrake((float)(((!this.close || this.vp.localVelocity.z > 0.1f) && (this.lookDot > 0f || this.vp.velMag <= 20f)) ? 0 : 1));
		}
		this.rolledOverTime = ((!this.va.rolledOver) ? 0f : (this.rolledOverTime + Time.fixedDeltaTime));
		if (this.rolledOverTime > this.rollResetTime && this.rollResetTime >= 0f)
		{
			base.StartCoroutine(this.ResetRotation());
		}
	}

	// Token: 0x06000583 RID: 1411 RVA: 0x0002B484 File Offset: 0x00029684
	private IEnumerator ReverseReset()
	{
		this.reverseAttempts = 0;
		this.reverseTime = 0f;
		yield return new WaitForFixedUpdate();
		this.tr.position = this.targetPoint;
		this.tr.rotation = Quaternion.LookRotation((!this.targetIsWaypoint) ? Vector3.forward : (this.targetWaypoint.nextPoint.transform.position - this.targetPoint).normalized, GlobalControl.worldUpDir);
		this.rb.velocity = Vector3.zero;
		this.rb.angularVelocity = Vector3.zero;
		yield break;
	}

	// Token: 0x06000584 RID: 1412 RVA: 0x0002B4A0 File Offset: 0x000296A0
	private IEnumerator ResetRotation()
	{
		yield return new WaitForFixedUpdate();
		this.tr.eulerAngles = new Vector3(0f, base.transform.eulerAngles.y, 0f);
		this.tr.Translate(Vector3.up, Space.World);
		this.rb.velocity = Vector3.zero;
		this.rb.angularVelocity = Vector3.zero;
		yield break;
	}

	// Token: 0x06000585 RID: 1413 RVA: 0x0002B4BC File Offset: 0x000296BC
	public void InitializeTarget()
	{
		if (this.target)
		{
			this.targetBody = (Rigidbody)F.GetTopmostParentComponent<Rigidbody>(this.target);
			this.targetWaypoint = this.target.GetComponent<VehicleWaypoint>();
			if (this.targetWaypoint)
			{
				this.prevSpeed = this.targetWaypoint.speed;
			}
		}
	}

	// Token: 0x040007B9 RID: 1977
	private Transform tr;

	// Token: 0x040007BA RID: 1978
	private Rigidbody rb;

	// Token: 0x040007BB RID: 1979
	private VehicleParent vp;

	// Token: 0x040007BC RID: 1980
	private VehicleAssist va;

	// Token: 0x040007BD RID: 1981
	public Transform target;

	// Token: 0x040007BE RID: 1982
	private Transform targetPrev;

	// Token: 0x040007BF RID: 1983
	private Rigidbody targetBody;

	// Token: 0x040007C0 RID: 1984
	private Vector3 targetPoint;

	// Token: 0x040007C1 RID: 1985
	private bool targetVisible;

	// Token: 0x040007C2 RID: 1986
	private bool targetIsWaypoint;

	// Token: 0x040007C3 RID: 1987
	private VehicleWaypoint targetWaypoint;

	// Token: 0x040007C4 RID: 1988
	public float followDistance;

	// Token: 0x040007C5 RID: 1989
	private bool close;

	// Token: 0x040007C6 RID: 1990
	[Range(0f, 1f)]
	[Tooltip("Percentage of maximum speed to drive at")]
	public float speed = 1f;

	// Token: 0x040007C7 RID: 1991
	private float initialSpeed;

	// Token: 0x040007C8 RID: 1992
	private float prevSpeed;

	// Token: 0x040007C9 RID: 1993
	public float targetVelocity = -1f;

	// Token: 0x040007CA RID: 1994
	private float speedLimit = 1f;

	// Token: 0x040007CB RID: 1995
	private float brakeTime;

	// Token: 0x040007CC RID: 1996
	[Tooltip("Mask for which objects can block the view of the target")]
	public LayerMask viewBlockMask;

	// Token: 0x040007CD RID: 1997
	private Vector3 dirToTarget;

	// Token: 0x040007CE RID: 1998
	private float lookDot;

	// Token: 0x040007CF RID: 1999
	private float steerDot;

	// Token: 0x040007D0 RID: 2000
	private float stoppedTime;

	// Token: 0x040007D1 RID: 2001
	private float reverseTime;

	// Token: 0x040007D2 RID: 2002
	[Tooltip("Time limit in seconds which the vehicle is stuck before attempting to reverse")]
	public float stopTimeReverse = 1f;

	// Token: 0x040007D3 RID: 2003
	[Tooltip("Duration in seconds the vehicle will reverse after getting stuck")]
	public float reverseAttemptTime = 1f;

	// Token: 0x040007D4 RID: 2004
	[Tooltip("How many times the vehicle will attempt reversing before resetting, -1 = no reset")]
	public int resetReverseCount = 1;

	// Token: 0x040007D5 RID: 2005
	private int reverseAttempts;

	// Token: 0x040007D6 RID: 2006
	[Tooltip("Seconds a vehicle will be rolled over before resetting, -1 = no reset")]
	public float rollResetTime = 3f;

	// Token: 0x040007D7 RID: 2007
	private float rolledOverTime;
}
